package com.ramnight.sql2.component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.ramnight.sql2.util.SqlKit;

public class Where {
	private boolean isOr = false;
	private StringBuilder sql = new StringBuilder();
	private ArrayList<Object> param = new ArrayList<>();
	
	Where(){
	}
	
	Where(boolean isOr){
		this.isOr = isOr;
	}
	
	/**
	 * 默认EQ
	 */
	Where(String key, Object value){
		eq(key, value);
	}
	
	Where(Map<String, Object> map){
		for(Entry<String, Object> entry : map.entrySet()){
			eq(entry.getKey(), entry.getValue());
		}
	}
	
	Where(String sql, Object...values){
		this.sql.append(sql);
		param.addAll(Arrays.asList(values));
	}
	
	public String sql(){
		return " where " + sql.toString();
	}
	
	public ArrayList<Object> param(){
		return param;
	}
	
	public Where eq(String key, Object value){
		param.add(value);
		return addRule(key, " = ? ");
	}
	
	public Where like(String key, Object value){
		param.add("%" + String.valueOf(value) + "%");
		return addRule(key, " like ? ");
	}
	
	public Where bt(String key, Object value){
		param.add(value);
		return addRule(key, " > ? ");
	}
	
	public Where lt(String key, Object value){
		param.add(value);
		return addRule(key, " < ? ");
	}
	
	public Where be(String key, Object value){
		param.add(value);
		return addRule(key, " >= ? ");
	}
	
	public Where le(String key, Object value){
		param.add(value);
		return addRule(key, " <= ? ");
	}
	
	public Where ne(String key, Object value){
		param.add(value);
		return addRule(key, " != ? ");
	}
	
	public Where isNull(String key){
		return addRule(key, " is null ");
	}
	
	public Where notNull(String key){
		return addRule(key, " is not null ");
	}
	
	public Where in(String key, Query query){
		param.addAll(Arrays.asList(query.param()));
		return addRule(key, " in " + SqlKit.wrapCurve(query.sql()));
	}
	
	public Where in(String key, Long...longs){
		return in(key, Arrays.asList(longs));
	}
	
	public Where in(String key, String...strs){
		return in(key, Arrays.asList(strs));
	}
	
	private Where in(String key, List<?> list){
		String part = SqlKit.concatPlaceholder(list.size());
		for(Object o : list){
			param.add(o);
		}
		return addRule(key, " in " + SqlKit.wrapCurve(part));
	}
	
	private Where addRule(String key, String rule){
		if(sql.length() > 0){
			sql.append(SqlKit.wrapBlank(isOr ? "or" : "and"));
		}
		sql.append(SqlKit.wrapCol(key)).append(rule);
		return this;
	}
	
	StringBuilder getSql(){
		return this.sql;
	}
	
	public Where and(Where where){
		sql.append(" and ").append(SqlKit.wrapCurve(where.getSql()));
		this.param.addAll(where.param());
		return this;
	}
	
	public Where add(String sql, Object...values){
		if(this.sql.length() > 0){
			this.sql.append(SqlKit.wrapBlank(isOr ? "or" : "and"));
		}
		 this.sql.append(SqlKit.wrapBlank(sql));
		 this.param.addAll(Arrays.asList(values));
		 return this;
	}
}
